﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.Serialization;
using System.Reflection;
using System.Diagnostics;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace ClassLibrary
{
	/// <summary>
	/// simple tests for ClassLibrary1/2
	/// </summary>
	[TestClass]
	public class ConvertExtensionTests
	{								
		[TestMethod]
		public void ConvertClass1Test()
		{			
			ClassLibrary1.Class1 src;
			ClassLibrary2.Class1 dest;			
			src = new ClassLibrary1.Class1
			{
				//struct1 = { category = "the category", id = 2023 }
				compositeType1 =
				new ClassLibrary1.CompositeType1
				{
					description = "the description ",
					composite2Collection = new List<ClassLibrary1.CompositeType2>
					{
						new ClassLibrary1.CompositeType2 { Total = 2100.02m, URI = "http://www.google.com" },
						new ClassLibrary1.CompositeType2 { Total = 3100.33m, URI = "http://www.bing.com"},
					},
				},
				Name = "object#1"
			};
			dest = ClassLibrary.ConvertExtension.Convert(src);			
		}
		[TestMethod]
		public void ConvertCompositeType4Test()
		{
			ClassLibrary1.CompositeType4 src;
			ClassLibrary2.CompositeType4 dest;

			src = new ClassLibrary1.CompositeType4
			{
				identifier = null,
				Width = 400.2,
				compositeType5 = new ClassLibrary1.CompositeType5
				{
					isEnabled = false, signedByte = -127
				}
			};
			dest = ClassLibrary.ConvertExtension.Convert(src);
		}

		//3 cases (1) IEnumerable (2) property Type equal (3) two different class types
		//use dynamic keyword? but the Type is known at generation (compile) time.

		static void setProperties(Type destType, Type srcType, string name)
		{
			//if (destType == srcType)
			//{
			//    Console.WriteLine("{0} = {1}", destName, srcName);
			//    return;
			//}

			var commonProperties = from destP in destType.GetProperties()
								   join srcP in srcType.GetProperties()
										on destP.Name equals srcP.Name
								   select new { desttype = destP.PropertyType, srctype = srcP.PropertyType, Name = srcP.Name };
			foreach (var common in commonProperties)
			{
				if (common.desttype == common.srctype)//base case: would-be return;
					Console.WriteLine("{0}.{1} = {2}.{3}", destType.Name, common.Name, srcType, common.Name);
				else
					setProperties(common.desttype, common.srctype, common.Name);
			}

			return;
		}

		static void attemptToSerialize<T>(T objects)
		{
			DataContractSerializer serializer = new DataContractSerializer(typeof(T));
			byte[] buffer;
			using (MemoryStream memstream = new MemoryStream())
			{
				serializer.WriteObject(memstream, objects);
				memstream.Position = 0;
				serializer.ReadObject(memstream);
				buffer = memstream.GetBuffer();
			}


		}
		public static void checkHelperExtensionT4()
		{
			string prefix;
			prefix = CommonT4.HelperExtensionT4.GetClassPrefix(typeof(ClassLibrary1.Class1));
			prefix = CommonT4.HelperExtensionT4.GetClassPrefix(typeof(ClassLibrary2.Class1));
		}


		private TestContext testContextInstance;

		/// <summary>
		///Gets or sets the test context which provides
		///information about and functionality for the current test run.
		///</summary>
		public TestContext TestContext
		{
			get
			{
				return testContextInstance;
			}
			set
			{
				testContextInstance = value;
			}
		}

		#region Additional test attributes
		//
		// You can use the following additional attributes as you write your tests:
		//
		// Use ClassInitialize to run code before running the first test in the class
		// [ClassInitialize()]
		// public static void MyClassInitialize(TestContext testContext) { }
		//
		// Use ClassCleanup to run code after all tests in a class have run
		// [ClassCleanup()]
		// public static void MyClassCleanup() { }
		//
		// Use TestInitialize to run code before running each test 
		// [TestInitialize()]
		// public void MyTestInitialize() { }
		//
		// Use TestCleanup to run code after each test has run
		// [TestCleanup()]
		// public void MyTestCleanup() { }
		//

		[TestInitialize]
		public void Tests_Initialize()
		{
			//set up Debug Tracing:
			//string path = Path.Combine(Environment.CurrentDirectory, @"WriteConvertType_Test.cs");
			//using (FileStream stream = new FileStream(path, FileMode.Create, FileAccess.Write))
			//{
			//    var textlistener = new TextWriterTraceListener(stream);
			//    Debug.Listeners.Add(textlistener);
			//    Debug.AutoFlush = true;
			//}
		}
		#endregion
	}
}
